////////////////////////////////////////////////////////////////
//
//       Filename:  SandboxDefault.go
//
//        Version:  1.0
//        Created:  2022年11月07日 13时23分34秒
//       Revision:  none
//       Compiler:  go
//
//         Author:  alpha
//   Organization:  alpha
//       Contacts:  chenxinquan@kylinos.com
//
////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////
// Description:
////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////
// Log:
////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////
// Todo:
//
////////////////////////////////////////////////////////////////

package Sandbox

import (
    "fmt"
    "os/exec"
    "bufio"
    "errors"
    "syscall"
    // "strings"
    inter "main/genmai/Interpreter"
)

// 继承与SandBoxBase接口
type
SandboxDefault struct {
}


///////////////////////////////
// override functions
func
(sbd *SandboxDefault)cmdGuard(execpath string) error {
    // TODO: Very Important
    A_DEBUG_ERROR("cmdGuard():NEED TO IMPLEMENT!")

    return nil
}
func
(sbd *SandboxDefault)Process(interpreter string,interArgs []string,execpoc string, args ...string) (inter.InterIO, error) {
    // var cmd []string
    // TODO: make ALOG
    A_DEBUG_INFO("Starting process for : ", GetSubfixPath(execpoc), " ...\n")

    // exec.Command will cause security problem, we must make a
    // strong guard

    if (nil != sbd.cmdGuard(execpoc)) {
        A_DEBUG_WARNING("Invalid Command!")
        return inter.InterIO{}, errors.New("Invalid Command!")
    }

    var cname string
    var arry []string
    if len(interpreter)==0 {
        cname = execpoc
        // cmd := exec.Command(execpoc,args...)
    }else{
        if len(interArgs) !=0{
            for i:=0;i<len(interArgs);i++{
                arry =append(arry,interArgs[i])
            }
        }
        cname = interpreter
        arry = append(arry,execpoc)
        arry = append(arry,args...)
        // cmd  := exec.Command(interpreter,arry...)
    }
    cmd  := exec.Command(cname,arry...)

    // 设置进程组属性，以便AfterFunc 调用Kill杀死进程组
    // see: ExplorerKernel.go:exploreWithPath() 和
    //      ExplorerSystem.go:exploreWithPath()
    cmd.SysProcAttr = &syscall.SysProcAttr{}
    cmd.SysProcAttr.Setpgid = true
    fmt.Println(cmd)
    ///////////////////////////////
    // build reader, writer
    stdin, rc := cmd.StdinPipe()
    /* */
    if (nil != rc) {
        return inter.InterIO{}, rc
    } // if (nil != ...
        
    stdout, rc := cmd.StdoutPipe()
    //stdout, rc := cmd.StderrPipe()
    if (nil != rc) {
        return inter.InterIO{}, rc
    } // if (nil != ...

    ///////////////////////////////
    // start
    rc = cmd.Start()
    if (nil != rc) {
        return inter.InterIO{}, rc
    } // if (nil ...
    A_DEBUG_INFO("\nbin: ", GetSubfixPath(execpoc), "\npid: ", cmd.Process.Pid, "\n")

    iio := inter.InterIO {
        Reader: bufio.NewReader(stdout),
        Writer: bufio.NewWriter(stdin),
        Cmd: cmd,
    }
    return iio, rc
}

